package structures;

import util.*;
import java.util.Hashtable;
import java.util.TreeSet;
import java.util.Vector;

public class DynamicGraph {
	private Hashtable<String, Hashtable<String, TreeSet<Date>>> nodes = new Hashtable<String, Hashtable<String, TreeSet<Date>>>();
	
	
	public DynamicGraph() {
		
	}
	
	/**
	 * Returns the number of nodes in the graph.  Pretty sure this works
	 * @return Number of nodes
	 */
	public int size() {
		return nodes.size();
	}
	
	/**
	 * If a node is not already in the graph, adds it.
	 * @param s
	 */
	
	public void addNode(String s) {
		if(! nodes.containsKey(s)) {
			nodes.put(s, new Hashtable<String, TreeSet<Date>>());
		}
	}
	
	/**
	 * Adds an edge between a and b at date d.
	 * @param a
	 * @param b
	 * @param d
	 */
	
	public void addEdge(String a, String b, Date d) {
		addNode(a);
		addNode(b);
		if(! nodes.get(a).containsKey(b)) {
			nodes.get(a).put(b, new TreeSet<Date>());
		}
		nodes.get(a).get(b).add(d);
	}
	
	public void addLink(String a, String b, Date d) {
		addEdge(a, b, d);
	}
	
	public void add(StaticGraph g, Date d) {
		StaticEdgeIterator i = g.iterator();
		while(i.hasNext()) {
			Object[] nextEdge = i.next();
			addLink((String) nextEdge[0], (String) nextEdge[1], d);
		}
	}
	
	public StaticGraph getTimeSlice(Date after, Date before) {
		StaticGraph g = new StaticGraph();
		for(String node : nodes.keySet()) {
			for(String node2 : nodes.get(node).keySet()) {
				for(Date d : nodes.get(node).get(node2)) {
					if(d.after(after) && d.before(before) || d.equals(before) || d.equals(after)) {
						g.incrementLink(node, node2);
					}
				}
			}
		}
		return g;
	}
	
	public Vector<String> getNodes() {
		Vector<String> nodes = new Vector<String>();
		for(String s : this.nodes.keySet()) {
			nodes.add(s);
		}
		return nodes;
	}
	
	public Vector<String> getNbrs(String node) {
		Vector<String> results = new Vector<String>();
		for(String s : nodes.get(node).keySet()) {
			results.add(s);
		}
		return results;
	}
	
	public StaticGraph getDay(Date d) {
		return getTimeSlice(d, d.nextDay());
	}

	public EdgeIterator iterator() {
		return new EdgeIterator(this);
	}
	
	public Date getLatestDate() {
		Date max = null;
		for(String s : nodes.keySet()) {
			for(String s2 : nodes.get(s).keySet()) {
				for(Date d : nodes.get(s).get(s2)) {
					if(max == null || d.after(max)) {
						max = d;
					}
				}
			}
		}
		return max;
	}
	
	public Date getEarliestDate() {
		Date min = null;
		for(String s : nodes.keySet()) {
			for(String s2 : nodes.get(s).keySet()) {
				for(Date d : nodes.get(s).get(s2)) {
					if(min == null || d.before(min)) {
						min = d;
					}
				}
			}
		}
		return min;
	}
	
	public TreeSet<Date> getEdge(String a, String b) {
		return nodes.get(a).get(b);
	}
	
	public String toString() {
		String str = "";
		EdgeIterator i = iterator();
		while(i.hasNext()) {
			Object[] o = i.next();
			str += o[0] + " " + o[1] + " " + o[2] + "\n";
		}
		return str;
	}




}
